package licode.unisop.realm.application.service;

import licode.unisop.provider.api.SiUserProvider;
import licode.unisop.provider.info.SiProviderFind;
import licode.unisop.realm.application.gateway.SiRealmModelGateway;
import licode.unisop.realm.application.gateway.SiUserProviderManager;
import licode.unisop.realm.client.api.SiRealmQueryService;
import licode.unisop.realm.client.dto.SiRealmDTO;
import licode.unisop.realm.domainx.model.RealmModel;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 使用缓存方式实现领域模型查询
 *
 * @author licode
 */
@Component
public class SiRealmModelGatewayCache implements SiRealmModelGateway {
    private static final String DEF_NAME = "default";

    @Resource
    private SiRealmQueryService siRealmQueryService;

    @Resource
    private SiUserProviderManager siUserProviderManager;

    private final ConcurrentHashMap<String, RealmModel> realmModels = new ConcurrentHashMap<>();

    @Override
    public RealmModel findRealmModel(String realmId) {
        return realmModels.computeIfAbsent(realmId, key -> {
            SiUserProvider provider;
            SiRealmDTO realmDTO = siRealmQueryService.findRealm(realmId);

            if (null == realmDTO) {
                if (DEF_NAME.equals(realmId)) {
                    realmDTO = SiRealmDTO.builder().providerId(DEF_NAME).build();
                } else {
                    return null;
                }
            }

            SiProviderFind providerFind = SiProviderFind.builder()
                    .realmId(realmId)
                    .providerId(realmDTO.getProviderId())
                    .build();

            provider = siUserProviderManager.findUserProvider(providerFind);

            return RealmModel.builder()
                    .realmId(realmId)
                    .provider(provider)
                    .build();
        });
    }

    @Override
    public RealmModel findDefaultRealmModel() {
        SiUserProvider provider;
        provider = siUserProviderManager.findUserProvider(SiProviderFind.builder()
                .realmId("")
                .providerId(DEF_NAME)
                .build());

        return RealmModel.builder()
                .realmId("")
                .provider(provider)
                .build();
    }
}
